/*
Copyright (c) [2019年5月1日] [吴超]
[MBT_Studio] is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
		 http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.
*/
#pragma once

//#include <algorithm>
#include <mutex>
#include <vector>
#include <map>
//#include <ppl.h>

#include <线性代数/几何计算.h>
#include <字符串转换.h>
#include <文件/file_载入保存数据.h>
#include <文件/加载保存属性.h>


#include <引擎数据类型.h>
#include <物体/物体.h>
#include <粒子/粒子.h>
#include <纹理/纹理.h>
#include <数学/数学.h>


#include <core/属性.h>
#include <core/引擎配置.h>
#include <core/几何计算/vec_array.h>
#include <core/mesh_container.h>
#include <core/vec_conversion.h>
#include <core/文件块.h>

//#include "编译声明代码.h"
#include "uiNodeLink.h"



#include <Python.h>


//================================= 物体 ========================================
#define DEF_摄像机节点			    "摄像机节点"
#define DEF_取物体节点			    "取物体节点"
#define DEF_引用物体节点		    "引用物体节点"
#define DEF_物体虚拟体节点		    "物体虚拟体节点"
#define DEF_取物体变换节点		    "取物体变换节点"
#define DEF_取物体矩阵节点		    "取物体矩阵节点"
#define DEF_设置物体变换节点        "设置物体变换节点"
#define DEF_设置物体矩阵节点        "设置物体矩阵节点"
#define DEF_查找子物体节点          "查找子物体节点"
#define DEF_设置摄像机属性节点      "设置摄像机属性节点"
#define DEF_外部加载物体节点        "外部加载物体节点"
#define DEF_加载模型节点            "加载模型节点"
#define DEF_选择物体节点            "选择物体节点"
#define DEF_多边形物体节点          "多边形物体节点"
#define DEF_目标摄像机节点          "目标摄像机节点"




//================================= 容器  变量 ========================================
#define DEF_变量引用节点			"变量引用节点"
#define DEF_I8变量节点				"I8变量节点"
#define DEF_I8数组变量节点			"I8数组变量节点"
#define DEF_浮点变量节点			"浮点变量节点"
#define DEF_整数变量节点			"整数变量节点"
#define DEF_无符号整数变量节点		"无符号整数变量节点"
#define DEF_F32数组变量节点			"F32数组变量节点"
#define DEF_I32数组变量节点			"I32数组变量节点"
#define DEF_UI32数组变量节点        "UI32数组变量节点"
#define DEF_vec2变量节点			"vec2变量节点"
#define DEF_vec3变量节点			"vec3变量节点"
#define DEF_ivec3变量节点			"ivec3变量节点"
#define DEF_vec2数组变量节点		"vec2数组变量节点"
#define DEF_vec3数组变量节点		"vec3数组变量节点"
#define DEF_ivec2数组变量节点		"ivec2数组变量节点"
#define DEF_ivec3数组变量节点		"ivec3数组变量节点"
#define DEF_Vec4数组变量节点		"Vec4数组变量节点"
#define DEF_多边形成员数组变量节点  "多边形成员数组变量节点"
#define DEF_44矩阵数组变量节点		"44矩阵数组变量节点"
#define DEF_矩阵构建节点			"矩阵构建节点"
#define DEF_构建变换矩阵节点		"构建变换矩阵节点"
#define DEF_构建旋转矩阵节点		"构建旋转矩阵节点"
#define DEF_线段变量节点			"线段变量节点"
#define DEF_线段1D变量节点			"线段1D变量节点"
#define DEF_坐标构建平面变量节点 	"坐标构建平面变量节点"

#define DEF_观察矩阵构建节点		"观察矩阵构建节点"
#define DEF_数组变量节点			"数组变量节点"
#define DEF_添加数组元素节点		"添加数组元素节点"
#define DEF_取数组属性节点			"取数组属性节点"
#define DEF_取数组元素节点			"取数组元素节点"
#define DEF_取数组头尾元素节点      "取数组末尾元素节点"
#define DEF_合并数组元素节点		"合并数组元素节点"
#define DEF_插入数组节点            "插入数组节点"
#define DEF_删除数组元素节点        "删除数组元素节点"
#define DEF_查找数组元素节点        "查找数组元素节点"
#define DEF_复制数组节点            "复制数组节点"

#define DEF_单值钳制节点			"单值钳制节点"
#define DEF_矢量钳制节点			"矢量钳制节点"
#define DEF_取内存邻接数据节点		"取内存邻接数据节点"
#define DEF_取空间邻接数据节点		"取空间邻接数据节点"
#define DEF_从坐标取数据节点		"从坐标取数据节点"
#define DEF_数组元素统计节点	    "数组元素统计节点"
#define DEF_数组打乱节点	        "数组打乱节点"
#define DEF_索引数组排序节点	    "索引数组排序节点"
#define DEF_数组重排节点		    "数组重排节点"
#define DEF_数组抽取节点		    "数组抽取节点"
#define DEF_合并数据节点		    "合并数据节点"



//================================= 字符串 ========================================
#define DEF_文件路径节点			"文件路径节点"
#define DEF_行字符串变量节点		"行字符串变量节点"
#define DEF_数值转字符串节点		"数值转字符串节点"
#define DEF_合并字符串节点			"合并字符串节点"




//============================================ 计算类名称 ====================================================
#define DEF_位运算节点			    "位运算节点"
#define DEF_单目计算节点			"单目计算节点"
#define DEF_累计计算节点			"累计计算节点"
#define DEF_四元数转换为欧拉角节点  "四元数转换为欧拉角节点"
#define DEF_四元数转换为4X4矩阵节点 "四元数转换为4X4矩阵节点"
#define DEF_矩阵转换节点			"矩阵转换节点"
#define DEF_顶点变换节点			"顶点变换节点"

#define DEF_几何计算节点			"几何计算节点"
#define DEF_平面向量节点			"平面向量节点"
#define DEF_平面到点节点			"平面到点节点"
#define DEF_三角函数节点			"三角函数节点"
#define DEF_归一化节点				"归一化节点"
#define DEF_两向量标量计算节点		"两向量计算标量节点"
#define DEF_向量角度组成四元数节点  "向量角度组成四元数节点"
#define DEF_旋转向量节点            "旋转向量节点"
#define DEF_按轴向旋转向量节点      "按轴向旋转向量节点"
#define DEF_向量标量计算节点		"向量计算标量节点"
#define DEF_四元数计算节点			"四元数计算节点"
#define DEF_四元变换节点			"四元变换节点"
#define DEF_两向量转四元数            "向量转四元数"
#define DEF_圆坐标生成节点			"圆坐标生成节点"
#define DEF_直线坐标生成节点		"直线坐标生成节点"
#define DEF_平面坐标生成节点		"平面坐标生成节点"
#define DEF_梯度采样节点			"梯度采样节点"
#define DEF_曲线采样节点			"曲线采样节点"
#define DEF_渐变采样节点			"渐变采样节点"
#define DEF_绕点旋转节点			"绕点旋转节点"
#define DEF_平面线段相交节点		"线段平面相交节点"
#define DEF_索引转坐标节点		    "索引转坐标节点"
#define DEF_坐标转索引节点		    "坐标转索引节点"
#define DEF_步进计算节点		    "步进计算节点"



#define DEF_回写节点				"回写节点"
#define DEF_逻辑计算节点			"逻辑计算节点"
#define DEF_矢量计算节点			"矢量计算节点"
#define DEF_合并XYZ节点				"合并XYZ节点"
#define DEF_分离XYZ节点				"分离XYZ节点"
#define DEF_设置矢量分量节点		"设置矢量分量节点"
#define DEF_单值计算节点			"单值计算节点"
#define DEF_混合计算节点			"混合计算节点"

#define DEF_射线物体相交节点		"射线物体相交节点"



//================================= 网格 多边形 模型 ========================================
#define DEF_网格节点			 "网格节点"
#define DEF_设置网格属性节点	 "设置网格属性节点"
#define DEF_填充网格顶点节点	 "填充网格顶点节点"
#define DEF_填充网格纹理坐标节点 "填充网格纹理坐标节点"
#define DEF_几何节点			 "几何节点"
#define DEF_几何ID节点			 "几何ID节点"
#define DEF_当前多边形节点       "当前多边形节点"
#define DEF_基本多边形节点		 "基本多边形节点"
#define DEF_多边形节点			 "多边形节点"
#define DEF_多边形面节点		 "多边形面节点"
#define DEF_多边形边节点		 "多边形边节点"
#define DEF_多边形顶点节点		 "多边形顶点节点"
#define DEF_多边形复制节点		 "多边形复制节点"
#define DEF_多边形拷贝节点		 "多边形拷贝节点"
#define DEF_多边形变换节点		 "多边形变换节点"
#define DEF_多边形四元数变换节点 "多边形四元数变换节点"
#define DEF_添加纹理坐标节点     "添加纹理坐标节点"
#define DEF_添加多边形元素节点   "添加多边形元素节点"
#define DEF_从索引构建面纹理坐标节点 "从索引构建面纹理坐标节点"
#define DEF_投影纹理坐标节点     "投影纹理坐标节点"
#define DEF_多边形添加顶点节点	 "多边形添加顶点节点"
#define DEF_多边形删除顶点节点	 "多边形删除顶点节点"
#define DEF_多边形索引节点       "多边形索引节点"
#define DEF_线倒角节点			 "线倒角节点"
#define DEF_多边形桥接节点		 "多边形桥接节点"
#define DEF_点桥接节点		     "点桥接节点"
#define DEF_多边形边网格化节点	 "多边形边网格化节点"
#define DEF_多边形边采样节点	 "多边形边采样节点"
#define DEF_取多边形面属性节点	 "取多边形面属性节点"
#define DEF_设置多边形面属性节点 "设置多边形面属性节点"
#define DEF_设置多边形面UV节点   "设置多边形面UV节点"
#define DEF_设置面材质槽ID节点   "设置面材质槽ID节点"
#define DEF_网格选择节点	     "网格选择节点"
#define DEF_多边形边实体化节点	 "多边形边实体化节点"
#define DEF_面朝向节点           "面朝向节点"
#define DEF_网格采样节点         "网格采样节点"
#define DEF_取多边形顶点元素节点 "取多边形元素节点"
#define DEF_取多边形面顶点节点   "取多边形面顶点节点"
#define DEF_设置多边形面顶点节点 "设置多边形面顶点节点"
#define DEF_设置网格元素顶点节点 "设置网格元素顶点节点"

#define DEF_多边形转网格节点           "多边形转网格节点"
#define DEF_取网格元素节点             "取网格元素节点"
#define DEF_取网格元素顶点节点         "取网格元素顶点节点"
#define DEF_取多边形边节点             "取多边形边节点"
#define DEF_取多边形面元素节点         "取多边形面元素节点"
#define DEF_创建网格自定义属性节点     "创建网格自定义属性节点"
#define DEF_设置网格面自定义属性节点   "设置网格自定义属性节点"
#define DEF_设置网格元素自定义属性节点 "设置网格元素自定义属性节点"




#define DEF_平行光节点			"平行光节点"
#define DEF_聚光灯节点			"聚光灯节点"
#define DEF_点光源节点			"点光源节点"
#define DEF_区域光节点			"区域光节点"


//================================= 材质 着色器 ========================================
#define DEF_材质槽节点                      "材质槽节点"
#define DEF_当前材质节点                    "当前材质节点"
#define DEF_材质编辑节点                    "材质节点"
#define DEF_着色器节点			            "着色器节点"
#define DEF_自发光材质节点		            "自发光材质节点"
#define DEF_纹理节点			            "纹理节点"
#define DEF_设置网格材质节点	            "设置物体材质节点"
#define DEF_设置材质节点		            "设置材质节点"
#define DEF_取物体材质节点		            "取物体材质节点"
#define DEF_取物体光追材质节点	            "取物体光追材质节点"
#define DEF_PBR着色器节点	                "设置PBR材质属性节点"
#define DEF_基于物理计算着色节点            "基于物理计算着色节点"
#define DEF_几何数据节点                    "几何数据节点"
#define DEF_光线数据节点                    "光线数据节点"
#define DEF_几何UV数据节点                  "几何UV数据节点"
#define DEF_材质器网格自定义属性数据节点    "材质网格自定义属性数据节点"









#define DEF_包节点      "包节点"
#define DEF_迭代节点	"迭代节点"
#define DEF_循环节点	"循环节点"
#define DEF_循环头节点	"循环头节点"
#define DEF_循环尾节点	"循环尾节点"
#define DEF_跳过节点	"跳过节点"
#define DEF_输入组节点	"输入组节点"
#define DEF_输出组节点	"输出组节点"
#define DEF_插座转接节点 "路由节点"
#define DEF_面板框节点   "面板框节点"
#define DEF_Python节点   "Python节点"
#define DEF_分支判断节点 "分支判断节点"
#define DEF_函数节点        "函数节点"
#define DEF_结构节点        "结构节点"
#define DEF_强化学习节点	"强化学习节点"

#define DEF_渲染器配置节点	"渲染器配置节点"
#define DEF_渲染输出节点	"渲染输出节点"

#define DEF_物理引擎节点	"物理引擎节点"
#define DEF_物理几何体节点	"物理几何体节点"
#define DEF_物理体节点		"物理体节点"
#define DEF_物理体绑定物体节点		"物理体绑定物体节点"
#define DEF_取物理体节点			"取物理体节点"
#define DEF_物理引擎内部几何节点	"物理引擎内部几何节点"
#define DEF_更新肌腱节点			"更新肌腱节点"
#define DEF_应用力节点				"应用力节点"





//============================================ 材质纹理 ====================================================
#define DEF_噪波纹理节点			"噪波纹理节点"
#define DEF_外部纹理节点			"外部纹理节点"
#define DEF_外部纹理集节点			"外部纹理集节点"
#define DEF_渐变纹理节点			"渐变纹理节点"
#define DEF_棋盘格纹理节点			"棋盘格纹理节点"
#define DEF_字符纹理节点			"字符纹理节点"
#define DEF_2D纹理采样节点			"纹理采样节点"
#define DEF_字符纹理坐标节点		"字符纹理坐标节点"
#define DEF_字符纹理排列节点		"字符纹理排列节点"
#define DEF_2D纹理数组采样节点		"2D纹理数组采样节点"




//============================================ 容器数据 ================================================

#define DEF_物体缓存节点			"物体缓存节点"
#define DEF_网格缓存写入节点		"网格缓存写入节点"
#define DEF_读取网格缓存节点		"读取网格缓存节点"


#define DEF_调试输出节点			"调试输出节点"
#define DEF_控制台输出节点			"控制台输出节点"







class C_节点基类;
class C_节点树;
class S_物体;




#define DEF_节点编译函数	f_编译(C_节点基类* rn, std::string& 声明, std::vector<std::string>& 定义, std::string& 释放)
typedef std::string(*fp_节点编译回调)(C_节点基类* self, std::string& 声明, std::vector<std::string>& 定义, std::string& 释放);


#define DEF_编译可调参数名称 参数
#define DEF_编译全局可调参数名称 g参数

#define DEF_编译可调参数 void*** 参数
#define DEF_编译全局可调参数 void*** g参数
#define DEF_编译全局可调参数赋值 g参数 = 参数


enum E_节点更新方式 {
	e_节点更新_被动,
	e_节点更新_逐帧,
	e_节点更新_实时,
};


enum E_插座方向 {
	e_插座Type_输入,
	e_插座Type_输出,
};


typedef struct {
	void* m_DataPoint;
	E_值类型 m_Type;
}S_属性数据;

typedef enum {
	e_编译成功,
	e_编译失败,
}S_编译状态;



enum E_节点类型 {
	e_节点Type_自定义,
	e_节点Type_Reroute,

	e_节点Type_包,
	e_节点Type_函数,
	e_节点Type_循环迭代,

	e_节点Type_判断,
	e_节点Type_迭代,
	e_节点Type_循环,
	e_节点Type_几何,

	e_节点Type_组输入,
	e_节点Type_组输出,

	e_节点Type_循环头,
	e_节点Type_循环尾,

	e_节点Type_材质,
	e_节点Type_材质设置,
	e_节点Type_着色器,
	e_节点Type_纹理,
	e_节点Type_解释器,

	e_节点Type_空物体,
	e_节点Type_物体,
	e_节点Type_几何线,
	e_节点Type_多边形,
	e_节点Type_网格,
	e_节点Type_骨架,
	e_节点Type_骨头,
	e_节点Type_约束,
	e_节点Type_灯光,
	e_节点Type_摄像机,
	e_节点Type_虚拟体,

	e_节点Type_计算,
	e_节点Type_转接,
	e_节点Type_框,
	e_节点Type_回调,
	e_节点Type_结构,

	e_节点Type_网格自定义属性,
	e_节点Type_字符串,
	
};




typedef enum  {
	e_赋值_None,
	e_赋值_添加,
	e_赋值_删除,

	e_赋值_直接,
	e_赋值_插入,
	e_赋值_插入头,
}E_数据赋值方式;

typedef struct {
	class C_插座基类*	m_插座;
	E_数据赋值方式		m_方式;
}S_插座增减方式;

typedef struct {
	C_插座基类* m_插座;
	int32		m_插座后端位置;
}S_添加的插座;

typedef struct {
	int32		m_插座后端位置;
	E_插座方向	m_方向;
}S_删除的插座;

typedef enum {
	e_局部,
	e_局部静态,
	e_全局
}E_节点数据布局;









typedef struct {
	S_粒子系统配置* m_Psy;
	S_粒子* m_粒子;
	S_物体* m_粒子点;
}S_粒子插座数据;






typedef struct {
	E_值类型		m_Type;
	void*			m_Data;
	uvec4			m_位置索引;
	E_数据赋值方式	m_添加方式;
	//virtual ~S_引用插座数据映射(){}
}S_引用插座数据映射;





struct S_插座图像数据  {
	std::vector<S_RGBA8UI>	m_像素;
	uvec3					m_维度;
	uint8					m_颜色位数;
};



typedef bool(*expand_接口函数_几何节点)(S_多边形* 多边形, int32 id, void** 函数参数, DEF_编译可调参数 );
typedef bool(*expand_接口函数_材质节点)(S_Material& material, int32 id, S_材质& 材质, void** inData, DEF_编译可调参数);
typedef bool(*expand_接口函数_函数节点)(void** 输入参数, DEF_编译可调参数, uint32 递归深度);

typedef void(*fun_插座UI更新)(class C_插座基类* socket);






class C_插座基类 {
	bool			m_回写插座;
	
protected:
	bool			m_是否为输出插座;
	bool			m_是否单输入插座;
	bool			m_映射指针;
	E_节点更新方式	m_更新方式;
	bool			m_联通;
	

	C_节点基类*		m_pNode;
	uint16			m_JIT参数ID;
	std::string		m_Code;
	std::vector<std::string> m_多输入代码;

	std::vector<S_NodeLink*>	m_p当前输出插座绑定连接线;
	//C_插座基类*				m_p输出插座_分流;
	std::vector<S_属性数据>		m_附带属性;
public:
	C_插座基类(std::wstring name, E_值类型 type = E_值类型::e_Type_Bool);
	virtual ~C_插座基类();

	std::wstring		m_identifier;
	std::wstring		m_Name;
	bool				m_有新数据;

	const E_值类型		m_Type;
	class C_Widget*		m_UI部件;
	fun_插座UI更新		on_UI更新;
	S_GPU内存块索引     m_GPU缓存;

	
	


	bool				f_isOut() { return m_是否为输出插座; }
	E_插座方向			f_get方向() { return m_是否为输出插座 ? E_插座方向::e_插座Type_输出 : E_插座方向::e_插座Type_输入; }
	bool				f_isLink();
	bool				f_is单链接() { return m_是否单输入插座; }
	bool				f_是否联通();
	bool				f_is回写() { return m_回写插座; }
	
	void				f_断开输出链接(S_NodeLink* link);
	virtual C_插座基类*					f_getLinkOutSocket(uint16 插座 = 0);
	virtual std::vector<C_插座基类*>	f_getLinkOutSocketGroup();
	

	virtual void*		f_getData(uint8 线程ID);
	virtual void*		f_getDefaultData() { return nullptr; }
	virtual E_JIT_FunParam	f_getJIT参数(uint8 线程ID, uint16 in_ID);
	//virtual void*		f_getData(const uvec4& id) { return 0; }
	virtual void		f_绑定指针(void* data){};
	virtual bool		f_接入插座是否匹配(E_值类型 type) { return true; }
	virtual bool		f_getBool(const uvec4& id);
	virtual S_GPU内存块索引& f_getGPU块(uint8 线程ID, bool 更新 = false);
	virtual S_GPU内存块索引& f_downGPU块(uint8 线程ID, bool 更新 = false);
	

	//返回新变量名称 或 内部变量
	//virtual std::string	f_构建变量代码();
	virtual std::string	f_构建变量代码(int32 多输入ID);
	std::string         f_getName();

	virtual void		f_setData(void* data, uint8 线程ID = 0);
	virtual void		f_setData(S_引用插座数据映射* data, uint8 线程ID = 0){}
	virtual void		f_set回写(bool is回写) { m_回写插座 = is回写; }
	virtual void		f_resize(uint64 ID, uint8 线程ID = 0) {}
	
	virtual void		f_释放数据() {}
	virtual void		f_删除元素(uint32 id, uint8 线程ID = 0) {}
	void				f_set多输入() { m_是否单输入插座 = false; }
	void				f_set单输入() { m_是否单输入插座 = true; }
	uint16				f_getJIT参数ID() { return m_JIT参数ID; }


	std::wstring		f_get所在节点名称();

	std::vector<C_节点基类*>	f_get链接到的输出插座节点();
	std::vector<C_插座基类*>	f_get链接到的输出插座();

	std::vector<C_节点基类*>	f_get链接到的输入插座节点();
	std::vector<C_插座基类*>	f_get链接到的输入插座();
	std::vector<C_插座基类*>	f_get直接链接到的输入插座();
	std::vector<S_NodeLink*>&	f_getLinkLines() { return m_p当前输出插座绑定连接线; }
	uint32						f_getLinkNum() { return m_p当前输出插座绑定连接线.size(); }

	virtual std::wstring		f_getTypeName() { return L""; }

	C_节点基类*			f_getNode() { return m_pNode; }
	//有链接则为接入的插座类型
	E_值类型			f_get接入的数据类型(int32 loc = 0);
	
	std::string			f_getCode(int32 loc);
	void				f_setCode(const std::string& code) { m_Code = code; };
	
	std::vector<void*>	f_get属性数据(E_值类型 type);


	virtual void		f_读取(FILE* f);
	virtual void		f_写入(FILE* f);
	virtual void        f_Copy(const C_插座基类* socket){}
	//摒弃
	C_插座基类* f_get输出数据的插座();
private:
	bool				f_Link(S_NodeLink* link);

	cpp友员				class C_节点基类;
	cpp友员				class C_插座基类;
	cpp友员				class S_NodeLink;

};











//带可视物体的节点记得设置节点类型
class C_节点基类 {
	bool			m_标记为更新路径中;
	bool			m_节点层级结构更新;
	C_节点树*		m_ThisTree;
	
protected:
	E_节点更新方式	m_更新方式;
	
	bool			m_是否要更新;
	
	C_节点树* m_子集节点树;
	C_节点树* m_当前节点所在节点树;

	std::vector<C_插座基类*> m_inputs;
	std::vector<C_插座基类*> m_outputs;

	
public:
	C_节点基类(std::string typeName, E_节点类型 type = E_节点类型::e_节点Type_自定义);
	virtual ~C_节点基类();

	vec2				m_坐标;
	S_RGBA8UI			m_颜色;
	std::string			m_ICO;

	std::wstring        m_Name;
	std::string			m_Code;
	std::string			m_ReleaseCode;
	//C_节点基类*			m_父节点;

	const std::string	m_TypeName;
	const E_节点类型	m_Type;

	
	std::set<C_Widget*>	m_包含在多个视口的UI部件;
	

	uint32			m_层;
	E_节点数据布局	m_数据布局;
	S_设备环境		m_Ctx;
	
	bool			m_插座可编辑;
	bool			m_是否有焦点;
	float32			m_耗时;
	uint8			m_更新时间;
	bool			m_插座改变后是否更新节点;
	bool			m_外部更新Bl节点;
	bool			m_是否释放数据;
	bool			m_并发;
	bool			m_标记区域;
	bool            m_冻结数据;
	bool            m_显示数据;
	bool            m_越过更新;
	bool			m_编译成功;

	S_Props         m_启用;


	C_节点基类*				m_区域父节点;
	std::set<C_节点基类*>	m_区域内节点;

	C_节点基类*               m_框节点;
	std::vector<C_节点基类*>  m_框包含节点;
	std::vector<std::wstring> m_框包含节点名称;
	


	virtual	void		f_add插座(C_插座基类* s, E_插座方向 方向, int32 loc = -1);
	virtual	void		f_del插座(const std::wstring name, E_插座方向 方向);
	virtual	void		f_del插座(uint32 loc, E_插座方向 方向);
	virtual	bool		f_释放插座数据(E_插座方向 方向);

	virtual	bool		f_移动插座(E_插座方向 方向, E_方向 上下, int16 step);
	virtual C_插座基类*	f_动态添加插座(E_插座方向 方向, std::vector<S_添加的插座>& 添加的插座) { return nullptr; }
	virtual int32		f_动态删除插座(E_插座方向 方向, std::vector<S_删除的插座>& 删除的插座) { return -1; }
	//以包含输入输出插座
	virtual int16		f_可添加删除插座起始位置(E_插座方向 方向) { return 1; }
	virtual void		f_set可添加删除插座起始位置(uint32 num) { }
	
	virtual void		f_插座连接事件(C_插座基类* 发生链接的输入插座) {};
	


	fp_节点编译回调		mf_编译;
	std::string         f_getName();
	std::wstring        f_getWName() { return m_Name; }
	void                f_setWName(const std::wstring name) { m_Name = name; }
	virtual std::string	f_编译(C_节点基类* rn, std::string& 声明, std::vector<std::string>& 定义, std::string& 释放);

	virtual bool		f_update() { return false; };
	virtual void		f_异步解算() {}
	virtual void		f_释放数据() {}
	
	virtual C_节点基类* f_创建实例() { return 0; }
	virtual void		f_绑定this节点树(C_节点树* tree) { 
							m_ThisTree = tree;
						}
	virtual void		f_绑定子集节点树(C_节点树* tree);
	virtual void		f_解绑定子集节点树();
	virtual C_节点树*	f_getThis节点树(const C_节点树* 当前节点树 = nullptr);
	virtual C_节点基类* f_getThis节点();
	C_节点树*			f_get所在节点树() { return m_当前节点所在节点树; }
	void				f_set所在节点树(C_节点树* tree);
	
	C_节点树*			f_get子集树() { return m_子集节点树; }
	


	virtual void		f_set是否要更新(bool update);
	virtual void		f_更新上层节点(bool 更新结构);
	
	bool			f_需要更新()		{ return (m_是否要更新 && !m_越过更新) || (f_getAN曲线数量() && S_物体::g_更新曲线关键帧); }
	bool			f_是否以更新()		{ return !m_是否要更新;	}
	bool			f_上层节点是否以更新();


	bool			f_层级结构需更新() { return m_节点层级结构更新; }
	bool			f_是否以更新层级结构() { return !m_节点层级结构更新; }
	void			f_标记层级结构需更新(bool update) { m_节点层级结构更新 = update; }
	bool			f_上层节点层级结构是否以更新();
	void			f_输入插座标记已读();
	void			f_标记输出插座新数据(uint16 loc, bool f, E_插座方向 方向);
	



	E_节点更新方式		f_get更新方式() { return m_更新方式; }
	void				f_set节点更新方式(E_节点更新方式 方式);

	uint16				f_get输入插座链接数量();
	uint16				f_get输出插座链接数量();

	C_插座基类*			f_get输入插座(const std::wstring& name);
	C_插座基类*			f_get输出插座(const std::wstring& name);

	int16				f_get输入插座Loc(C_插座基类* name);
	int16				f_get输出插座Loc(C_插座基类* name);
	int16				f_get输入插座Loc(const std::wstring& name);
	int16				f_get输出插座Loc(const std::wstring& name);

	const C_插座基类*   f_get输入插座(uint32 id) const;
	C_插座基类*			f_get输入插座(uint32 id);
	C_插座基类*			f_get输出插座(uint32 id);

	uint32				f_get输入插座Num() const { return uint32(m_inputs.size()); }
	uint32				f_get输出插座Num() const { return uint32(m_outputs.size()); }

	uint16				f_get输出插座连接数量();
	uint16				f_get多输入插座数量();

	//void				f_断开输入链接(uint32 socketID);
	void				f_替换插座(C_插座基类* socket, uint16 loc, E_插座方向 方向);
	void				f_替换插座(std::vector<C_插座基类*>& sockets, E_插座方向 方向);
	//void				f_set输出插座连接线(std::vector<S_NodeLink*>& sockets);

	void				f_get下层节点(std::vector<C_节点基类*>& 下层节点);
	void				f_set下层节点为需要更新();
	
	

	
	void				f_构建附属节点(std::map<std::wstring, C_节点基类*>& nodes);

	virtual void		f_读取(FILE* f);
	virtual void		f_写入(FILE* f);

	virtual void		f_写入插座(FILE* f);
	virtual void		f_读取插座(std::map<std::wstring, C_节点基类*>& nodes, FILE* f);
	
	virtual void		f_写入插座链接(FILE* f);
	virtual void		f_读取插座链接(FILE* f, std::map<std::wstring, C_节点基类*>& nodes);
	

	virtual S_物体*		f_get虚拟体();
	virtual void		f_入回收() {}
	virtual void		f_回收() {}
	virtual void          f_Show(bool open){}
	virtual S_动画曲线组* f_getAN曲线();
	virtual uint32        f_getAN曲线数量(){return 0;}
	virtual void          f_getStr(std::vector<std::vector<std::wstring>>& 文本){}

	virtual void          f_Copy(const C_节点基类* node);
private:

};





#define DEF_节点名称 \
	string 树名称 = f_Wchar_tToString(treeName);		\
	string 节点名称 = f_Wchar_tToString(nodeName);		\
														\
	C_节点树* tree = f_getTree(树名称);					\
	C_节点基类* node = tree->f_getNode(节点名称);		\



typedef C_节点基类* (*fp_加载节点函数)(S_设备环境& ctx, FILE* f);
typedef void		(*fp_保存节点函数)(C_节点基类* node, FILE* f);









struct S_节点插座类型名称 {
	std::wstring m_i8;
	std::wstring m_i16;
	std::wstring m_i32;
	std::wstring m_i64;
	std::wstring m_i128;
	std::wstring m_f16;
	std::wstring m_f32;
	std::wstring m_f64;
	std::wstring m_ui8;
	std::wstring m_ui16;
	std::wstring m_ui32;
	std::wstring m_ui64;
	std::wstring m_ui128;
	
	std::wstring m_ivec2;
	std::wstring m_ivec3;
	std::wstring m_ivec4;
	std::wstring m_uivec2;
	std::wstring m_uivec3;
	std::wstring m_uivec4;

	std::wstring m_vec2;
	std::wstring m_vec3;
	std::wstring m_vec4;

};



std::string f_node_getDataTypeName(E_值类型 type);

void f_node_销毁程序集(class C_节点树* 子集节点树);

void f_node_移除插座准备销毁(C_插座基类* socket);
void f_node_销毁插座();




